package com.cea.papyrus.diagram.classdiagram.commands;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.uml2.uml.Classifier;
import org.eclipse.uml2.uml.ClassifierTemplateParameter;
import org.eclipse.uml2.uml.Generalization;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.ParameterableElement;
import org.eclipse.uml2.uml.TemplateParameterSubstitution;
import org.eclipse.uml2.uml.UMLFactory;

import com.cea.papyrus.core.commands.PapyrusCommand;

public class ElementOwnedByATemplateParameterSubstitutionCreateCommand extends PapyrusCommand {

	
	/**
	 * Created element.
	 */
	private ParameterableElement createdOwnedElement ;
	
	/**
	 * parent of the created element.
	 */
	private TemplateParameterSubstitution umlParentTemplateParameterSubstitution ;
	
	/**
	 * generalization created when an owned default is created,
	 * and the template parameter is a ClassifierTemplateParameter,
	 * and the classifier template parameter has a constraining classifier
	 */
	private Generalization createdGeneralization ;
	
	/**
	 * element metaclass.
	 */
	private EClass elementMetaClass ;
	
	public ElementOwnedByATemplateParameterSubstitutionCreateCommand(EClass elementMetaClass, Class elementClass, TemplateParameterSubstitution umlParentParameterSubstitution) {
//		super(elementClass) ;
		this.umlParentTemplateParameterSubstitution = umlParentParameterSubstitution ;
		this.elementMetaClass = elementMetaClass ;
		this.createdGeneralization = null ;
		super.setLabel("Creation of an owned actual parameter") ;
	}
	
	public void execute() {
		umlParentTemplateParameterSubstitution.getActuals().clear() ;
		createdOwnedElement = umlParentTemplateParameterSubstitution.createOwnedActual(elementMetaClass) ;
		((NamedElement)createdOwnedElement).setName("ActualFor" + ((NamedElement)umlParentTemplateParameterSubstitution.getFormal().getParameteredElement()).getName()) ;
		if (umlParentTemplateParameterSubstitution.getFormal() instanceof ClassifierTemplateParameter) {
			ClassifierTemplateParameter classifierTP = (ClassifierTemplateParameter)umlParentTemplateParameterSubstitution.getFormal() ;
			if (classifierTP.getConstrainingClassifier() != null) {
				createdGeneralization = UMLFactory.eINSTANCE.createGeneralization() ;
				createdGeneralization.setGeneral(classifierTP.getConstrainingClassifier()) ;
				createdGeneralization.setSpecific((Classifier)createdOwnedElement) ;
			}
		}
	}
	
	public boolean canExecute() {
		return umlParentTemplateParameterSubstitution instanceof TemplateParameterSubstitution ; 
	}
	
	public void redo() {
		execute() ;
	}
	
	public void undo() {
		umlParentTemplateParameterSubstitution.getOwnedActuals().remove(createdOwnedElement) ;
		umlParentTemplateParameterSubstitution.getActuals().remove(createdOwnedElement) ;
		if (createdGeneralization != null) {
			createdGeneralization.setGeneral(null) ;
			createdGeneralization.setSpecific(null) ;
		}
	}
	
	public boolean canUndo() {
		return createdOwnedElement != null ;
	}
	
	public boolean canRedo() {
		return createdOwnedElement != null ;
	}
}
